import * as math from 'mathjs';
export class Plugin {
    constructor() {
        this.name = ''; // 插件名称，例如 SUM、AVG
    }

    /**
    * 执行插件逻辑
    * @param {Array} args - 插件参数，例如 [A1, A2, B1, B2]
    * @returns {number} - 计算结果
    */
    execute(args) {
        throw new Error('Plugin.execute() must be implemented');
    }
}

export class ExpressionParser {
    constructor() {
        this.plugins = new Map(); // 存储所有插件
        this.cellValues = new Map(); // 存储单元格的值
    }

    /**
     * 注册插件
     * @param {Plugin} plugin - 插件实例
     */
    registerPlugin(plugin) {
        this.plugins.set(plugin.name, plugin);
    }
    

    
    /**
     * 获取 #key 格式的值
     * @param {string} key - 例如 key1
     * @returns {number} - 对应的值
     */
    getKeyValue(key) {
        const container = document.getElementById(key);
        if (!container) return 0;

        const input = container.querySelector('input');
        const select = container.querySelector('select');

        if (input) {
            return parseFloat(input.value) || 0;
        } else if (select) {
            return parseFloat(select.value) || 0;
        } else {
            return 0;
        }
    }

    /**
     * 获取表格单元格的值
     * @param {string} cell - 单元格标识，例如 A1
     * @returns {number} - 单元格的值
     */
    getCellValue(cell) {
        const td = document.querySelector(`#renderTb td[_index="${cell}"]`);
        if (!td) return { [cell]: 0 }; // 返回一个包含默认值的对象
        let modelType = td.getAttribute('modelType');
        const input = td.querySelector('input');
        const select = td.querySelector('select');
        const span = td.querySelector('span');
        console.log(cell,'cell getCellValue');
        if(modelType == "2"){
            let obj = {}
            if (input) {
                obj[cell] = parseFloat(input.value) || 0;

               
            } else if (select) {
                obj[cell] = parseFloat(select.value) || 0;
            } else {
                obj[cell] = 0;
            }
            return obj
        }else{
            let obj = {}
            if (input) {
                obj[cell] = input.value
            }else if(select){
                obj[cell] = select.value
            }else if(span){
                obj[cell] = span.innerText
            }else{
                obj[cell] = td.innerText
            }
            return obj
        }


        
    }

    /**
     * 将列字母转换为数字（例如：A -> 1，AA -> 27）
     * @param {string} column - 列字母，如 'A' 或 'AA'
     * @returns {number} - 对应的数值
     */
    columnToNumber(column) {
        column = column.toUpperCase();
        let num = 0;
        for (let i = 0; i < column.length; i++) {
            const charCode = column.charCodeAt(i) - 64; // 'A' 对应 1
            num = num * 26 + charCode;
        }
        return num;
    }

    /**
     * 将数字转换为列字母（例如：1 -> A，27 -> AA）
     * @param {number} num - 列对应的数值
     * @returns {string} - 列字母
     */
    numberToColumn(num) {
        let column = '';
        while (num > 0) {
            const remainder = (num - 1) % 26;
            column = String.fromCharCode(65 + remainder) + column;
            num = Math.floor((num - 1) / 26);
        }
        return column;
    }

    /**
     * 解析范围语法，例如 A1:B2
     * @param {string} range - 范围字符串，例如 A1:B2
     * @returns {Array} - 单元格值数组，顺序为 A1, A2, ..., B1, B2, ..., B9
     */
    parseRange(range) {
        const [start, end] = range.split(':');
        const startCol = start.match(/[A-Za-z]+/)[0];
        //const startCol =  start.match(/\$\{([A-Za-z]+\d+)\}/g)[0]
        const startRow = parseInt(start.match(/\d+/)[0]);
        const endCol = end.match(/[A-Za-z]+/)[0];
        //const endCol = end.match(/\$\{([A-Za-z]+\d+)\}/g)[0];
        const endRow = parseInt(end.match(/\d+/)[0]);

        const startColNum = this.columnToNumber(startCol);
        const endColNum = this.columnToNumber(endCol);

        const values = [];
        for (let colNum = startColNum; colNum <= endColNum; colNum++) {
            const colLetter = this.numberToColumn(colNum);
            for (let row = startRow; row <= endRow; row++) {
                const cell = `${colLetter}${row}`;
                values.push(this.getCellValue(cell));
            }
        }
        return values;
    }
    /**
     * 解析并执行表达式
     * @param {string} expression - 表达式，例如 SUM(A1:B2) + if(A1 > 10, A1 * 2, A1 + 5)
     * @returns {number | any} - 计算结果
     */
     parseExpression(expression) {
        try {
            // 解析 if 和 for 语法，转换成 JavaScript 可执行的表达式
            expression = this.parseControlFlow(expression);

            // 解析插件方法，例如 SUM(A1:B2)
            const methodRegex = /(\w+)\(([^)]+)\)/g;
            let match;
            let replacedExpression = expression;

            while ((match = methodRegex.exec(expression)) !== null) { 
                const methodName = match[1]; // 例如 SUM
                const argsString = match[2] ; // 例如 A1:B2,5,"hello"
                const _argsString = argsString.replace(/\$\{([^}]+)\}/g, "$1");
                if (methodName === "if" || methodName === "for") {
                    continue; // if 和 for 已经解析过，跳过
                }

                // 解析参数
                const args = _argsString.split(',').map(arg => {
                    arg = arg.trim();

                    if ((arg.startsWith('"') && arg.endsWith('"')) || (arg.startsWith("'") && arg.endsWith("'"))) {
                        return arg.slice(1, -1);
                    } else if (arg.includes(':')) {
                        console.log(arg,'arg ::')
                        return this.parseRange(arg);
                    }// 新增：处理布尔值（如 true/false）
                    else if (arg === 'true' || arg === 'false') {
                        return arg// 直接转换为布尔类型
                    } else if (!isNaN(parseFloat(arg))) {
                        return parseFloat(arg);
                    } else {
                        return this.getCellValue(arg);
                    }
                });

                const plugin = this.plugins.get(methodName);
                if (plugin) {
                    console.log(args,'args args')
                    const result = plugin.execute(args);
                    console.log(result,'result result')
                    // **关键修改：如果返回值是字符串，确保用引号包裹**
                    if (typeof result === 'string') {
                        replacedExpression = replacedExpression.replace(match[0], `"${result}"`);
                        console.log(replacedExpression,'replacedExpression result')
                    } else {
                        replacedExpression = replacedExpression.replace(match[0], result);
                    }
                    //replacedExpression = replacedExpression.replace(match[0], result);
                } else {
                    console.error(`Plugin not found: ${methodName}`);
                }
            }

            // 解析单元格变量
            const cellRegex = /\$\{([A-Za-z]+\d+)\}/g;
            //const cellRegex = /([A-Za-z]+\d+)/g;
            while ((match = cellRegex.exec(replacedExpression)) !== null) {
                const cell = match[1];
                const value = this.getCellValue(cell)[cell];
                replacedExpression = replacedExpression.replace(match[0], value);
            }

            // **执行 JavaScript 代码**
            return this.evaluateJS(replacedExpression);
        } catch (e) {
            console.error("Error evaluating expression:", e);
            return null;
        }
    }

    /**
     * 解析 if 和 for 语法
     * @param {string} expression - 例如 "if(A1 > 10, A1 * 2, A1 + 5)" 或 "for(i=1; i<=5; i=i+1, A1 + i)"
     * @returns {string} - 解析后的 JavaScript 表达式
     */
    parseControlFlow(expression) {
        // 解析 if 语法：if(A1 > 10, A1 * 2, A1 + 5) -> (A1 > 10 ? A1 * 2 : A1 + 5)
        expression = expression.replace(/if\(([^,]+),([^,]+),([^)]+)\)/g, (_, condition, trueValue, falseValue) => {
            return `(${condition.trim()} ? ${trueValue.trim()} : ${falseValue.trim()})`;
        });

        // 解析 for 语法：for(i=1; i<=3; i=i+1, A1 + i)
        expression = expression.replace(/for\(([^;]+);([^;]+);([^,]+),([^)]+)\)/g, (_, init, condition, increment, body) => {
            return `(() => {
                let result = [];
                for (${init.trim()}; ${condition.trim()}; ${increment.trim()}) {
                    result.push(${body.trim()});
                }
                return result;
            })()`;
        });

        return expression;
    }

    /**
     * 执行 JavaScript 代码（支持 if, for）
     * @param {string} expression - 解析后的表达式
     * @returns {any} - 计算结果
     */
    evaluateJS(expression) {
        console.log(expression,'expression js')
        try {
            return Function(`"use strict"; return (${expression});`)();
        } catch (e) {
            console.error("Error evaluating JavaScript expression:", e);
            return null;
        }
    }
    
    buildDependencyGraph() {
        const graph = new Map();
        const cells = document.querySelectorAll('td[_index]');

        cells.forEach(cell => {
            const cellId = cell.getAttribute('_index');
            const depend = cell.getAttribute('depend');
            const dependencies = depend ? depend.split(',') : [];
            graph.set(cellId, dependencies);
        });

        return graph;
    }

    /**
     * 拓扑排序
     * @param {Map} graph - 依赖图
     * @returns {Array} - 排序后的单元格列表
     */
    topologicalSort(graph) {
        const visited = new Set();
        const sorted = [];

        const visit = (node) => {
            if (visited.has(node)) return;
            visited.add(node);

            const dependencies = graph.get(node) || [];
            dependencies.forEach(dependency => visit(dependency));

            sorted.push(node);
        };

        graph.forEach((_, node) => visit(node));
        return sorted;
    }

    /**
     * 计算所有单元格的值
     */
    calculateAllCells() {
        const graph = this.buildDependencyGraph();
        const sortedCells = this.topologicalSort(graph);
        sortedCells.forEach(cell => {
            const value = this.getCellValue(cell);
            this.cellValues.set(cell, value);
        });
    }
}





//if(B2 > 10, 1, 2)